package com.changgou.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.changgou.search.pojo.SkuInfo;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 描述
 *
 * @author ljh
 * @version 1.0
 * @package com.changgou.search.service.impl *
 * @Date 2019-11-29
 * @since 1.0
 */
@Component
public class SearchResultMapperImpl implements SearchResultMapper {

    //手动进行结果集映射
    @Override
    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
        //1.获取当前的页的对象
        List<T> content = new ArrayList<T>();
        //2.获取分页的对象
        //....
        //3.获取总记录数
        SearchHits hits = response.getHits();

        if(hits==null || hits.getTotalHits()<=0){
            return new AggregatedPageImpl<T>(content);
        }
        // 3.5 获取高亮的数据
        for (SearchHit hit : hits) {
            //{}
            String sourceAsString = hit.getSourceAsString();//无高亮的数据    JSON
            //  //判断是否有高亮数据,如果没有高亮值 返回无高亮的数据   object
            SkuInfo skuInfo = JSON.parseObject(sourceAsString, SkuInfo.class);
            //T skuInfo = JSON.parseObject(sourceAsString, clazz);

           /* Method[] declaredMethods = clazz.getDeclaredMethods();
            for (Method declaredMethod : declaredMethods) {
                String name = declaredMethod.getName();
                if(name.equals("setName")){
                    //可以了可以调用了
                    declaredMethod.invoke(skuInfo,sb.toString());
                }
            }*/
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();//高亮的数据

            //获取高亮字段name的高亮数据
            HighlightField highlightField = highlightFields.get("name");


            if(highlightField!=null){
                //如果有高亮的数据 获取高亮的数据设置到 无 高亮数据中
                StringBuffer sb = new StringBuffer();//高亮的数据了
                Text[] fragments = highlightField.getFragments();//高亮碎片
                for (Text fragment : fragments) {
                    String string = fragment.string();//高亮数据
                    sb.append(string);
                }
                skuInfo.setName(sb.toString());//将原来不高亮的值替换成高亮的值
            }

            content.add((T)skuInfo);
        }

        //4.获取聚合函数的结果集
        Aggregations aggregations = response.getAggregations();

        //5.获取深度分页用的游标的ID
        String scrollId = response.getScrollId();

        return new AggregatedPageImpl<T>(content,pageable,hits.getTotalHits(),aggregations,scrollId);
    }
}
